using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;
using Serilog;
using Serilog.Events;
using SqlSugar;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using TestWebApi.IServices;
using TestWebApi.Services;
using TestWebApi.Util;

var builder = WebApplication.CreateBuilder(args);
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.FromLogContext()
    .WriteTo.Async(c => c.Console(
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} | [{Level:u3}] | {Message:lj}{NewLine}{Exception}",
        restrictedToMinimumLevel: LogEventLevel.Information
    )) // 控制台日志级别为Information，并过滤特定日志
    .Filter.ByExcluding(logEvent => logEvent.Level == LogEventLevel.Information &&
                                    logEvent.Properties["SourceContext"].ToString().StartsWith("Microsoft.AspNetCore"))
    .CreateLogger();
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddEndpointsApiExplorer();  // 添加 Swagger
builder.Services.AddControllers();
builder.Services.AddSingleton<JwtHelper>(); // 注册数据服务 DataService为接口的具体实现 更换为其他实现类可直接切换 这也是DI的一种优势
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddSingleton<DatabaseContext>();
builder.Services.AddSingleton<IDataService, DataService>();
builder.Services.AddAuthorization();
//配置SqlSugar
builder.Services.AddSingleton<ISqlSugarClient>(x =>
{
    var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
    return new SqlSugarClient(new ConnectionConfig()
    {
        ConnectionString = connectionString,
        DbType = DbType.MySql,
        // InitKeyType = InitKeyType.Attribute, //从实体类特性中读取主键和自增列（有待确定是不是自增主键）
        IsAutoCloseConnection = true,
    });
});
AppLogger.Information("程序Swagger初始化完成");
// 添加Jwt认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.TokenValidationParameters =  new TokenValidationParameters
    {
        // 是否验证签名密钥
        ValidateIssuerSigningKey = true,
        // 签名密钥（实际项目中应从配置文件读取）
        IssuerSigningKey =
            new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"] ??
                                       throw new InvalidOperationException("JWT SecretKey 未配置"))
            ), // 密钥
        // 是否验证发行方
        ValidateIssuer = true,
        // 合法的发行方（可以设置为你的应用名称或URL）
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        
        // 是否验证受众
        ValidateAudience = true,
        // 合法的受众（可以设置为你的客户端应用标识）
        ValidAudience = builder.Configuration["Jwt:Audience"],
        
        // 是否验证令牌有效期
        ValidateLifetime = true
    };
});
AppLogger.Information("程序Jwt认证服务初始化完成");
// 配置 Swagger/OpenAPI 文档
builder.Services.AddSwaggerGen(options =>
{
    /*
  * ========================
  * Step 1: 定义 JWT 安全方案
  * ========================
  */
 options.SwaggerDoc("v1", new OpenApiInfo
 {
     Title = "My API",
     Version = "v1.0",
     Description = "这是一个受 JWT 保护的 API 示例。",
     Contact = new OpenApiContact
     {
         Name = "API Support",
         Url = new Uri("https://gitee.com/huangfu-superman/projects")
     }
 });
 /*
  * ========================
  * Step 2: 定义 JWT 安全方案
  * ========================
  * 这告诉 Swagger UI 和 Scalar：这个 API 使用 Bearer Token 进行身份验证。
  * 它会在 UI 上显示一个 "Authorize" 按钮，允许用户输入 token。
  */
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        // 描述信息，显示在 UI 上
        Name = "Authorization",   // HTTP 头名称
        Type = SecuritySchemeType.Http,   
        In = ParameterLocation.Header,   // Token 放在请求头中
        Scheme = "bearer",                         // 使用 Bearer 认证
        BearerFormat = "JWT"                       // 提示客户端这是一个 JWT
       
    });
    /*
     * ========================
     * Step 3: 应用安全要求
     * ========================
     * 这告诉 Swagger UI 为所有 API 端点应用 JWT 认证要求
     */
    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>() // 空数组表示不需要特定的 scope（适用于 JWT）
        }
    });
    
});


// 配置跨域
builder.Services.AddCors(
    options =>
    {
        options.AddPolicy("AllowAll", builder =>
        {
            builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
        });
    }
);
var app = builder.Build();
app.UseCors("AllowAll");
AppLogger.Information("程序跨域初始化完成");
app.MapOpenApi(); // 映射OpenAPI,以便访问API参考文档（无论是swagger,还是scalar）
// 添加认证
app.UseAuthentication();
// 添加授权
app.UseAuthorization();
// 添加scalar
app.MapScalarApiReference();
AppLogger.Information("程序Scalar文档初始化完成");
// 添加https重定向
app.UseHttpsRedirection();
app.MapControllers();
app.UseSwagger(new SwaggerOptions());
app.UseSwaggerUI(options =>
    {
      
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1"); 
      //  options.SwaggerEndpoint("/openapi/v1.json", "My API v1"); // ✅ 正确路径
        options.RoutePrefix = "swagger"; // 访问路径：/swagger
    //    options.ConfigObject.AdditionalItems["showServers"] = false; //禁用 Servers 下拉框
  
        // ✅ 强制显示 Authorize 按钮（v5 新增选项）
        //options.OAuthUsePkce(); 
    }
);
// // Configure the HTTP request pipeline. 只有开发环境才启用
// if (app.Environment.IsDevelopment())
// {
//     app.MapOpenApi();
//     // 添加SwaggerUI
//options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1"); // ✅ 正确路径
//     app.UseSwaggerUI(options => { options.SwaggerEndpoint("/openapi/v1.json", "v1"); });
//     //映射Scalar的API参考文档路径
//     app.MapScalarApiReference();
// }
app.Run();
AppLogger.Information("程序启动完成");
